package edu.cmu.arch.pipesandfilters;

import java.io.IOException;
import java.util.ArrayList;

import edu.cmu.arch.pipesandfilters.frame.Variable;

/**
 * Plumber test class.  Tests functionaltiy of reject filters and the merging 
 * of multiple sources based on time.
 *   
 * @author Steven Thomas (steventh@andrew.cmu.edu)
 */
public class Plumber {
	public static void main( String argv[]) {
//		//These will probably get passed in on the command line in the
//		//final version of the project.
//		String fileName1 = "DataSets/FlightData.dat";	// Input data file.
//		String fileName2 = "DataSets/SubSetB.dat";	// Input data file.
//		String outputFileName1 = "DataSets/OutputA.dat"; // Output data file
//		// Filter constructors
//		SourceFilter sourceFilter = new SourceFilter(fileName1);
//		SourceFilter sourceFilter2 = new SourceFilter(fileName2);
//		JoinerFilter joinerFilter = new JoinerFilter();
//		SinkFilter sinkFilter = new SinkFilter();
//		//AdvancedFileSink advanced = new AdvancedFileSink();	
//		WildPointFilter wildPointFilter = new WildPointFilter(
//				Variable.Pressure, new Double(50), new Double(80));
//
//		///////////////////////////////////////////////////////////////
//		// Michael: Not sure if this is the right way to do it
//		// The header could be an enumeration defined in the FormatFilter
//		ArrayList<Variable> headerA = new ArrayList<Variable>();//header for system A
//		headerA.add(Variable.Time);
//		headerA.add(Variable.Temperature);
//		headerA.add(Variable.Altitude);		
//		FileSinkFilter fileSinkFilter = null;
//		try {
//			fileSinkFilter = new FileSinkFilter(headerA, outputFileName1, "\t");
//		} catch (IOException e) {
//			System.out.println("Error creating sink filter");
//			System.exit(0);
//		}
//
//		
//		
//		//test of two source filters into one joiner
//		joinerFilter.Connect(sourceFilter, sourceFilter2);
//		//wildPointFilter.Connect(joinerFilter); //issues with pipe 2 in wild point filter 
//		sinkFilter.Connect(joinerFilter);
//		
//		// TODO: Michael: this is to connect 2 input ports to one filter or 2 output ports of the filter?
//		//advanced.Connect2(wildPointFilter);
//
//		// Name the threads so that we can tell what's going on in the
//		// system console
//		sourceFilter.setName("Thread::SourceFilter");
//		sourceFilter2.setName("Thread::SourceFilter2");
//		joinerFilter.setName("Thread::JoinerFilter");
//		//wildPointFilter.setName("Thread::WildPointFilter");
//		sinkFilter.setName("Thread::SinkFilter");
//
//		sourceFilter.start();
//		sourceFilter2.start();
//		joinerFilter.start();
//		//wildPointFilter.start();
//		sinkFilter.start();
//		//advanced.start();
		
		// Add individual tests to subroutines so that we don't step on
		// each other as we test our changes.
		// testDualOutputPorts(); 
	    // testPortReplication();
		// testTimeSequentialMerge();
		 testRejectFilters();
		 //TestTimeSequentialMergeFilter();
		
		
	}

	
	
	
	
	/**
	 *  Test rejectFilters
	 */
	public static void testRejectFilters()
	{
		String fileName1 = "DataSets/FlightData.dat";
		SourceFilter sourceFilter = new SourceFilter(fileName1);
		
		FileSinkFilter fileSink = null; 
		FileSinkFilter fileSinkRange = null;
		FileSinkFilter fileSinkExtrapolate = null;
		ArrayList<Variable> variablesToKeep = new ArrayList<Variable>();
		variablesToKeep.add(Variable.Time);
		variablesToKeep.add(Variable.Temperature);
		variablesToKeep.add(Variable.Altitude);
		try{
		fileSink = new FileSinkFilter(variablesToKeep,"DataSets/OutputTest.dat");
		fileSinkRange =new FileSinkFilter(variablesToKeep,"DataSets/RangeExceptions.dat");
		fileSinkExtrapolate = new FileSinkFilter(variablesToKeep,"DataSets/WildPoints.dat");
		
		}catch(IOException eio)
		{
			System.out.println("Plumber::testRejectFilters() IOException occured; " + eio.getMessage());
		}
		
		
		ExtrapolateFilter extrapolate = 
			new ExtrapolateFilter(Variable.Pressure,new Double(45),new Double(90));
		RangeFilter rangeFilter = 
			new RangeFilter(Variable.Temperature,new Double(5), Variable.Pressure ,new Double(65) );
		
		
		fileSink.Connect(rangeFilter);
		fileSinkRange.Connect(rangeFilter.getOutputFilter2());
		
		rangeFilter.Connect(extrapolate);
		fileSinkExtrapolate.Connect(extrapolate.getOutputFilter2());
		
		extrapolate.Connect(sourceFilter);
		
		sourceFilter.start();
		extrapolate.start();
		fileSinkExtrapolate.start();
		rangeFilter.start();
		fileSinkRange.start();
		fileSink.start();
	}
	
	public static void TestTimeSequentialMergeFilter()
	{
		String fileName1 = "DataSets/SubSetA.dat";
		String fileName2 = "DataSets/SubSetB.dat";
		
		SourceFilter sourceFilterA = new SourceFilter(fileName1);
		SourceFilter sourceFilterB = new SourceFilter(fileName2);
		FileSinkFilter fileSink = null;
		ArrayList<Variable> variablesToKeep = new ArrayList<Variable>();
		variablesToKeep.add(Variable.Time);
		variablesToKeep.add(Variable.Temperature);
		variablesToKeep.add(Variable.Altitude);
		
		try {
		  fileSink = new FileSinkFilter(variablesToKeep,"DataSets/OutputSort.dat");
		} catch (IOException e) {
			System.out.println("Plumber::TestTimeSequentialMergeFilter() IOException occured; " + e.getMessage());
			e.printStackTrace();
		}
		TimeSequentialMergeFilter merge = new TimeSequentialMergeFilter();
		
		merge.Connect(sourceFilterA, sourceFilterB);
		fileSink.Connect(merge);
		
        sourceFilterA.start();
        sourceFilterB.start();
        merge.start();
        fileSink.start();
		
	}
	
	
}
